package a.thread;

import java.lang.ref.WeakReference;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;

public abstract class AsyncTaskWrapper<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {

    public interface AsyncTaskCallback<Result> {
        void onTaskCompleted(Result result);
        void onCancelled();
    }

    /**
     * The task name for debug purpose
     */
    protected String TAG = null;
    /**
     * The progress dialog showing while the task is executing in the background
     */
    protected ProgressDialog mProgressDialog = null;
    /**
     * The weak reference to hosting Activity
     */
    protected WeakReference<Activity> mActivity;
    protected AsyncTaskCallback<Result> mCallback;

    public AsyncTaskWrapper(String taskName, Activity activity) {
        TAG = taskName;
        attach(activity, false);
    }

    /**
     * Set callback for AsyncTask
     * 
     * @param callback
     */
    public void setCallback(AsyncTaskCallback<Result> callback) {
        mCallback = callback;
    }

    @Override
    protected void onPreExecute() {
        showProgressDialog();
    }

    @Override
    protected void onPostExecute(Result result) {
        hideProgressDialog();
        if (mCallback != null) {
            mCallback.onTaskCompleted(result);
        }
    }

    @Override
    protected void onCancelled() {
        hideProgressDialog();
        if (mCallback != null) {
            mCallback.onCancelled();
        }
    }

    /**
     * Reattach this task to hosting Activity
     * 
     * @param callback the Activity to reattach
     */
    public void reattach(Activity activity) {
        attach(activity, true);
    }

    private void attach(Activity activity, boolean showDialog) {
        mActivity = new WeakReference<Activity>(activity);
        if (showDialog) {
            showProgressDialog();
        }
    }

    /**
     * Detach this task from hosting Activity
     */
    public void detach() {
        mActivity.clear();
        hideProgressDialog();
    }

    /**
     * Show progress dialog if any
     */
    protected void showProgressDialog() {
        Activity activity = mActivity.get();
        if (getStatus() != Status.FINISHED && activity != null) {
            mProgressDialog = createProgressDialog();
            if (mProgressDialog != null) {
                mProgressDialog.show();
            }
        }
    }

    /**
     * Hide progress dialog if any
     */
    protected void hideProgressDialog() {
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
    }

    public String getTaskName() {
        return TAG;
    }

    protected abstract ProgressDialog createProgressDialog();
}
